package cn.majingjing.core.json;

import java.io.IOException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;

/**
 * @description:
 * 
 * @author: Administrator - JingjingMa
 * @Email: <a href="majinding888@163.com">majinding888@163.com</a>
 * @date: 2015-5-10 下午9:38:36
 * @version 6.0
 * @DevTool: Created By Eclipse 4.3
 * 
 */

public class JacksonUtil {
	private static Logger log = LoggerFactory.getLogger(JacksonUtil.class);

	// private static ObjectMapper objectMapper = new ObjectMapper();
	private static ObjectMapper objectMapper = new ObjectMappingCustomer();

	public static ObjectMapper getObjectMapper() {
		return objectMapper;
	}

	/**
	 * <pre>
	 * 使用泛型方法，把json字符串转换为相应的JavaBean对象。
	 * (1)转换为普通JavaBean：readValue(json,Student.class)
	 * (2)转换为List:readValue(json,List.class).但是如果我们想把json转换为特定类型的List，比如List<Student>，就不能直接进行转换了。
	 *  因为readValue(json,List.class)返回的其实是List<Map>类型，你不能指定readValue()的第二个参数是List<Student>.class，所以不能直接转换。
	 *  我们可以把readValue()的第二个参数传递为Student[].class.然后使用Arrays.asList();方法把得到的数组转换为特定类型的List。
	 * (3)转换为Map：readValue(json,Map.class)
	 * 我们使用泛型，得到的也是泛型
	 * </pre>
	 * 
	 * @param content
	 *            要转换的JavaBean类型
	 * @param valueType
	 *            原始json字符串数据
	 * @return JavaBean对象
	 */
	public static <T> T readValue(String content, Class<T> valueType) {
		try {
			return objectMapper.readValue(content, valueType);
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	
	public static <T> T readValue(String content, TypeReference<T> valueTypeRef) {
		try {
			return objectMapper.readValue(content, valueTypeRef);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}

	/**
	 * 把JavaBean转换为json字符串 (1)普通对象转换：toJson(Student) (2)List转换：toJson(List)
	 * (3)Map转换:toJson(Map) 我们发现不管什么类型，都可以直接传入这个方法
	 * 
	 * @param object
	 *            JavaBean对象
	 * @return json字符串
	 */
	public static String toJson(Object object) {
		try {
			String json = objectMapper.writeValueAsString(object);
			// log.info(json);
			return json;
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;
	}
	
	public static String toJsonPrettyPrinter(Object object) {
		try {
			String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
			// log.info(json);
			return json;
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}

}

class ObjectMappingCustomer extends ObjectMapper {

	/**
	 * 
	 */
	private static final long serialVersionUID = -636605426387816680L;

	public ObjectMappingCustomer() {
		super();
		// 允许单引号
		this.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
		// 字段和值都加引号
		this.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
		// 数字也加引号
		this.configure(JsonGenerator.Feature.WRITE_NUMBERS_AS_STRINGS, true);
		this.configure(JsonGenerator.Feature.QUOTE_NON_NUMERIC_NUMBERS, true);
		//this.configure(JsonGenerator.Feature.IGNORE_UNKNOWN, true);
		this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES,false);
		// 空值处理为空串
		this.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
			@Override
			public void serialize(Object value, JsonGenerator jg, SerializerProvider sp) throws IOException,
					JsonProcessingException {
				jg.writeString("");
			}
		});

	}
}
